package com.digiregistry.api.wrapper.converters;


import com.digiregistry.api.wrapper.model.File;
import com.digiregistry.api.wrapper.model.FileTimestamp;
import com.digiregistry.api.wrapper.model.FileUser;
import com.digiregistry.api.wrapper.model.HashAlgorithm;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;

public class FileConverter extends ModelConverter {
	
	public FileConverter() {
		super(File.class);
	}
	
	private FileUserConverter userConverter = new FileUserConverter();
	
	@Override
	public void marshal(Object source, HierarchicalStreamWriter writer,
			MarshallingContext context) {
		File file = (File)source;
		// Marshal only updatable fields
		marshalField(context, writer, file, "name");
		marshalField(context, writer, file, "storageKey");
		marshalField(context, writer, file, "sourceUrl");
		if (file.getSize() > 0) {
			marshalField(context, writer, file, "size");
		}
		marshalField(context, writer, file, "md5");
		marshalField(context, writer, file, "sha1");
		marshalField(context, writer, file, "metadata");
	}

	@Override
	public Object unmarshal(HierarchicalStreamReader reader,
			UnmarshallingContext context) {
		File f = new File();
        while(reader.hasMoreChildren()) {
            reader.moveDown();
            String field = reader.getNodeName();
            if (field.equals("timestamps")) {
            	readTimestamps(f, reader, context);
            }
            else if (field.equals("users")) {
            	readUsers(f, reader, context);
            }
            else {
            	Object value = context.convertAnother(f, getFieldClass(field));
	            setFieldValue(f, field, value);            	
            }
            reader.moveUp();
        }
		return f;
	}

	private void readTimestamps(File f, HierarchicalStreamReader reader,
			UnmarshallingContext context) {
		f.getTimestamps().clear();
		while (reader.hasMoreChildren()) {
			reader.moveDown();
			reader.moveDown();
			String provider = reader.getValue();
			reader.moveUp();
			reader.moveDown();
			HashAlgorithm alg = Enum.valueOf(HashAlgorithm.class, reader.getValue());
			reader.moveUp();
			reader.moveDown();
			String value = reader.getValue();
			reader.moveUp();
			reader.moveUp();
			f.getTimestamps().add(new FileTimestamp(provider, alg, value));
		}
	}

	private void readUsers(File f, HierarchicalStreamReader reader,
			UnmarshallingContext context) {
		f.getUsers().clear();
		while (reader.hasMoreChildren()) {
			reader.moveDown();
			FileUser u = (FileUser)context.convertAnother(f, FileUser.class, userConverter);
			reader.moveUp();
			u.setFileId(f.getId());
			f.getUsers().add(u);
		}
	}
}
